#include "stdafx.h"
#include "ThumbListUI.h"


void CopyRectIn(const RECT &rcIn, RECT &rcOut)
{
	rcOut.bottom = rcIn.bottom;
	rcOut.left = rcIn.left;
	rcOut.right = rcIn.right;
	rcOut.top = rcIn.top;
}

CThumbListUI::CThumbListUI(void)
{
	m_nThumbWidth = 180;
	m_nThumbHeight = 130;
	m_nHorizontalSplitSize = 30;
	m_nVerticalSplitSize = 40;

	m_nOrderFontSize = 7;
	m_nOrderColor = 4294967295;
	m_nOrderBkcolor = 4278190080;

	m_nBorderColorIn = 4294967295;
	m_nBorderColorSelIn = 4278190080;

	m_nTextFontSize = 7;
	m_nTextColor = 4294967295;

	m_nCurSelRow = 0;
	m_nSrcllSize = 0;
	m_nRowCount = 0;
	m_nShowRowCount = 0;

	m_bMouseBnDwon = false;
}



LPCTSTR CThumbListUI::GetClass(void) const
{
	return  _T("ThumbListUI");
}

LPVOID CThumbListUI::GetInterface(LPCTSTR pstrName)
{
    if( _tcscmp(pstrName, _T("ThumbList")) == 0 ) 
		return static_cast<CThumbListUI*>(this);
    return CContainerUI::GetInterface(pstrName);
}

bool CThumbListUI::AddItem(CControlUI* pControl, int iIndex)
{
	((CThumbListItemUI*)pControl)->SetOrderBkColor(m_nOrderBkcolor);
	((CThumbListItemUI*)pControl)->SetOrderColor(m_nOrderColor);
	((CThumbListItemUI*)pControl)->SetOrderFontsize(m_nOrderFontSize);

	((CThumbListItemUI*)pControl)->SetBorderColorIn(m_nBorderColorIn);
	((CThumbListItemUI*)pControl)->SetBorderColorSelIn(m_nBorderColorSelIn);
	((CThumbListItemUI*)pControl)->SetTextFontSize(m_nTextFontSize);
	((CThumbListItemUI*)pControl)->SetTextColor(m_nTextColor);

	return AddAt(pControl,iIndex);
}
void CThumbListUI::DoPaint(HDC hDC, const RECT& rcPaint)
{
	CContainerUI::DoPaint(hDC, rcPaint);

	RECT				Itemrect;
	CThumbListItemUI	*pControl=NULL;
	int					nHCount = (m_rcItem.right-m_rcItem.left-m_nHorizontalSplitSize)/((double)(m_nThumbWidth+m_nHorizontalSplitSize));
	int					nRow = 0, nCol =0, nRowCount=0,nLeftItem=0;
	int					nXPos=0, nYPos=0;
	int					nTureHorizontalSplitSize;
	int					cyNeed, sizeyRc, scrollWidth = 0;
	int					nOffsetY = 0;

	{
		RECT rcTemp = { 0 };
		if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) )
			return;
	}
	sizeyRc = m_rcItem.bottom-m_rcItem.top;

	if (nHCount == 0)
		return;

	m_nShowRowCount = sizeyRc/((double)(m_nThumbHeight + m_nVerticalSplitSize));

	nRowCount =  m_items.GetSize()/nHCount;
	nLeftItem = m_items.GetSize()%nHCount;
	if (nLeftItem>0)
		nRowCount += 1;

	m_nRowCount = nRowCount;
	cyNeed = nRowCount*(m_nThumbHeight + m_nVerticalSplitSize) ;

	if (SetScrollbar(cyNeed, sizeyRc, scrollWidth))
	{
		nOffsetY = m_pVerticalScrollbar->GetScrollPos() ;
	}
	nTureHorizontalSplitSize = ((m_rcItem.right-m_rcItem.left) - nHCount*m_nThumbWidth-scrollWidth)/nHCount;
	
	m_nSrcllSize = m_nThumbHeight + m_nVerticalSplitSize;
	 for( int it = 0; it < m_items.GetSize(); it++ ) 
	 {
        pControl = static_cast<CThumbListItemUI*>(m_items[it]);
		if (pControl)
		{
          nRow = it/((double)nHCount);
		  nCol = it%nHCount;

		  nYPos = m_rcItem.top + nRow*(m_nThumbHeight + m_nVerticalSplitSize) + m_nVerticalSplitSize/2;
		  nXPos = m_rcItem.left + nCol*(m_nThumbWidth + nTureHorizontalSplitSize) + nTureHorizontalSplitSize/2;

		  Itemrect.left = nXPos;
		  Itemrect.top = nYPos - nOffsetY;
		  Itemrect.right = nXPos + m_nThumbWidth;
		  Itemrect.bottom = nYPos + m_nThumbHeight-nOffsetY;

		  if (Itemrect.top>0 && Itemrect.top<m_nThumbHeight + m_nVerticalSplitSize)
		  {
			  m_nCurSelRow = nRow;
		  }
		  pControl->SetPos(Itemrect);
		  pControl->DrawItem2(hDC);
		  //pControl->DrawItem(hDC, Itemrect);
        }
    }
}

void CThumbListUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
    if( _tcscmp(pstrName, _T("thumbwidth")) == 0 ) 
		m_nThumbWidth = _ttoi(pstrValue);
	else if (_tcscmp(pstrName, _T("thumbheight")) == 0 )
		m_nThumbHeight =_ttoi(pstrValue);
    else if (_tcscmp(pstrName, _T("horizontalspace")) == 0 )
		m_nHorizontalSplitSize = _ttoi(pstrValue);
	else if (_tcscmp(pstrName, _T("verticalspace")) == 0 )
		m_nVerticalSplitSize = _ttoi(pstrValue);
	else if (_tcscmp(pstrName, _T("itemorderfontsize")) == 0 )
		m_nOrderFontSize = _ttoi(pstrValue);
	else if (_tcscmp(pstrName, _T("itemordercolor")) == 0 )
		m_nOrderColor = _ttoi(pstrValue);
	else if (_tcscmp(pstrName, _T("itemorderbkcolor")) == 0 )
		m_nOrderBkcolor = _ttoi(pstrValue);
	else if (_tcscmp(pstrName, _T("itemtextsize")) == 0 )
		m_nTextFontSize = _ttoi(pstrValue);
	else if (_tcscmp(pstrName, _T("itemtextcolor")) == 0 )
		m_nTextColor = _ttoi(pstrValue);
	else if (_tcscmp(pstrName, _T("itembordercolor")) == 0 )
		m_nBorderColorIn = _ttoi(pstrValue);
	else if (_tcscmp(pstrName, _T("itemborderselcolor")) == 0 )
		m_nBorderColorSelIn = _ttoi(pstrValue);
    else
		CContainerUI::SetAttribute(pstrName, pstrValue);
}

void CThumbListUI::SetScrollPos(SIZE szPos)
{
	int cx = 0;
    int cy = 0;
    if( m_pVerticalScrollbar && m_pVerticalScrollbar->IsVisible() ) 
	{
        int iLastScrollPos = m_pVerticalScrollbar->GetScrollPos();
        m_pVerticalScrollbar->SetScrollPos(szPos.cy);
        cy = m_pVerticalScrollbar->GetScrollPos() - iLastScrollPos;
    }

    if( cx == 0 && cy == 0 ) 
		return;

    RECT rcPos;
    for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) 
	{
        CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);
        if( !pControl->IsVisible() ) continue;
        if( pControl->IsFloat() ) continue;

        rcPos = pControl->GetPos();
        rcPos.left -= cx;
        rcPos.right -= cx;
        rcPos.top -= cy;
        rcPos.bottom -= cy;
        pControl->SetPos(rcPos);
    }

    Invalidate();

}

void CThumbListUI::Scroll(int dx, int dy)
{
}
bool CThumbListUI::SetScrollbar(int cyNeed, int sizeyRc, int &scrollWidth)
{
	if( m_pVerticalScrollbar != NULL ) 
	{
		if (cyNeed > sizeyRc)
		{
			 scrollWidth = 16;
			 if( m_pVerticalScrollbar->IsVisible() ) 
			 {
				 m_pVerticalScrollbar->SetScrollRange(cyNeed - sizeyRc);
			 }
			 else
			 {
				 m_pVerticalScrollbar->SetVisible(true);
				 m_pVerticalScrollbar->SetScrollRange(cyNeed - sizeyRc);
				 m_pVerticalScrollbar->SetScrollPos(0);
			 }

			CRect rc = m_rcItem;

			// Adjust for inset
			rc.left = m_rcItem.right;
			rc.top = m_rcItem.top;
			rc.right = m_rcItem.right - scrollWidth;
			rc.bottom = m_rcItem.bottom;
			 ProcessScrollbar(rc, 0, cyNeed);
			 m_pVerticalScrollbar->Invalidate();

			 return true;
		}
		else
		{
			if( m_pVerticalScrollbar->IsVisible() ) 
			{
				m_pVerticalScrollbar->SetScrollRange(0);
				m_pVerticalScrollbar->SetScrollPos(0);
				m_pVerticalScrollbar->SetVisible(false);
			}
		}
	}
       
	return false;
}

SIZE CThumbListUI::GetScrollPos() const
{
	SIZE size;
	size.cx = 0;
	size.cy = 0;

	if( m_pVerticalScrollbar != NULL ) 
		size.cx = size.cy = m_pVerticalScrollbar->GetScrollPos();
	
	return size;
}

SIZE CThumbListUI::GetScrollRange() const
{
	SIZE size;
	size.cx = 0;
	size.cy = 0;
	if( m_pVerticalScrollbar != NULL ) 
		size.cy = m_pVerticalScrollbar->GetScrollRange();
	
	return size;
}


void CThumbListUI::Event(TEventUI& event)
{
    if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) 
	{
        if( m_pParent != NULL ) m_pParent->Event(event);
        else 
			CContainerUI::Event(event);
        return;
    }

    if( event.Type == UIEVENT_SETFOCUS ) 
    {
        m_bFocused = true;
        return;
    }
    if( event.Type == UIEVENT_KILLFOCUS ) 
    {
        m_bFocused = false;
        return;
    }
	if( event.Type == UIEVENT_BUTTONDOWN)
	{
		m_ptOld = m_ptOldDragstart = event.ptMouse;
		m_bMouseBnDwon = true;
	}
	if( event.Type == UIEVENT_BUTTONUP)
	{
		if (m_bMouseBnDwon)
			MouseUpDrag(event.ptMouse);
		m_bMouseBnDwon = false;
	}
	

	if (UIEVENT_MOUSEMOVE == event.Type && m_bMouseBnDwon)
	{
		if( !IsEnabled() ) 
			return;
		MouseMoveDrag(event.ptMouse);
		return;
	}
	if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )
    {
        if( !IsEnabled() ) 
			return;

		SelectsubItem(event.ptMouse);
     //  if( ::PtInRect(&m_rcButton1, event.ptMouse) ) {
	}

    switch( event.Type ) {
    case UIEVENT_KEYDOWN:
        switch( event.chKey ) {
        case VK_UP:
			MoveUp();
            return;
        case VK_DOWN:
            MoveDown();
            return;
        case VK_PRIOR:
            PageUp();
            return;
        case VK_NEXT:
            PageDown();
            return;

		case VK_DELETE:
			DeleteSelItem();
			return;
       
            }
        break;
    case UIEVENT_SCROLLWHEEL:
        {
            switch( LOWORD(event.wParam) ) 
			{
            case SB_LINEUP:
				{
					MoveUp();
				}
                return;
            case SB_LINEDOWN:
				{
					MoveDown();
				}
                return;
            }
        }
        break;
    }
    CControlUI::Event(event);
}
void CThumbListUI::MoveUp()
{
	int nYpos = 0;

	if (m_pVerticalScrollbar)
	{
		if (m_nCurSelRow>=0)
		{
			m_nCurSelRow--;
			nYpos = m_pVerticalScrollbar->GetScrollPos()-m_nSrcllSize;
			m_pVerticalScrollbar->SetScrollPos(nYpos);
			Invalidate();
		}
	}

}

void CThumbListUI::MoveDown()
{
	int nYpos = 0;

	if (m_pVerticalScrollbar)
	{
		if (m_nCurSelRow<=m_nRowCount)
		{
			m_nCurSelRow++;
			nYpos = m_pVerticalScrollbar->GetScrollPos()+m_nSrcllSize;
			m_pVerticalScrollbar->SetScrollPos(nYpos);
			Invalidate();
		}
	}
}

void CThumbListUI::PageUp()
{
	int nYpos = 0;

	if (m_pVerticalScrollbar)
	{
		if (m_nCurSelRow>=0)
		{
			m_nCurSelRow--;
			nYpos = m_pVerticalScrollbar->GetScrollPos()-m_nShowRowCount*m_nSrcllSize;
			m_pVerticalScrollbar->SetScrollPos(nYpos);
		}
	}
}

void CThumbListUI::PageDown()
{
	int nYpos = 0;

	if (m_pVerticalScrollbar)
	{
		if (m_nCurSelRow<=m_nRowCount)
		{
			m_nCurSelRow++;
			nYpos = m_pVerticalScrollbar->GetScrollPos()+m_nShowRowCount*m_nSrcllSize;
			m_pVerticalScrollbar->SetScrollPos(nYpos);
		}
	}
}
void CThumbListUI::SelectsubItem(POINT &pt)
{
	CThumbListItemUI	*pControl=NULL;

	for( int it = 0; it < m_items.GetSize(); it++ ) 
	 {
        pControl = static_cast<CThumbListItemUI*>(m_items[it]);
		if (pControl)
		{
			pControl->SelectIt(pt);
		}
	}

}

void CThumbListUI::MouseUpDrag(POINT &pt)
{
	CThumbListItemUI	*pControl=NULL, *pControl1=NULL;
	int					nIndex = GetSelectItem(), nCenterXTmp;
	POINT				ptOffset, ptDragCenter;
	RECT				rcTmp;
	int					nDisRight = -1, nDisLeft = -1, nRightItem=-1, nLeftItem=-1;

	if (nIndex == -1)
		return;
	pControl = static_cast<CThumbListItemUI*>(m_items[nIndex]);
	
	ptOffset.x = pt.x - m_ptOldDragstart.x;
	ptOffset.y = pt.y - m_ptOldDragstart.y;

	pControl->DrawDragItem(ptOffset);

	pControl->GetItemRect(rcTmp);
	ptDragCenter.x = (rcTmp.left + rcTmp.right)/2 + ptOffset.x;
	ptDragCenter.y = (rcTmp.bottom + rcTmp.top)/2 + ptOffset.y;

	for( int it = 0; it < m_items.GetSize(); it++ ) 
	{
        pControl1 = static_cast<CThumbListItemUI*>(m_items[it]);
		if (pControl1)
		{
			pControl1->GetItemRect(rcTmp);
			if (ptDragCenter.y < rcTmp.bottom && ptDragCenter.y > rcTmp.top)
			{
				nCenterXTmp = (rcTmp.left + rcTmp.right)/2 ;

				if (nCenterXTmp>ptDragCenter.x)
				{
					if (nDisRight == -1)
					{
						nDisRight = nCenterXTmp-ptDragCenter.x;
						nRightItem = it;
					}
					else
					{
						if (nDisRight>nCenterXTmp-ptDragCenter.x)
						{
							nDisRight = nCenterXTmp-ptDragCenter.x;
							nRightItem = it;
						}
					}
				}
				else
				{
					if (nDisLeft == -1)
					{
						nDisLeft = ptDragCenter.x-nCenterXTmp;
						nLeftItem = it;
					}
					else
					{
						if (nDisLeft>ptDragCenter.x-nCenterXTmp)
						{
							nDisLeft = ptDragCenter.x-nCenterXTmp;
							nLeftItem = it;
						}
					}
				}
			}
		}
	}
	if (nRightItem == -1)
		nRightItem = nLeftItem+1;

	MoveItem(nIndex, nRightItem);
	Invalidate();
}

void CThumbListUI::MouseMoveDrag(POINT &pt)
{
	CThumbListItemUI	*pControl=NULL;
	int					nIndex = GetSelectItem();
	POINT				ptOffset;
	

	if (nIndex == -1)
		return;

	pControl = static_cast<CThumbListItemUI*>(m_items[nIndex]);

	ptOffset.x = m_ptOld.x - m_ptOldDragstart.x;
	ptOffset.y = m_ptOld.y - m_ptOldDragstart.y;

	if (ptOffset.x !=0 || ptOffset.y != 0)
		pControl->DrawDragItem(ptOffset);

	m_ptOld = pt;
	ptOffset.x = pt.x - m_ptOldDragstart.x;
	ptOffset.y = pt.y - m_ptOldDragstart.y;

	pControl->DrawDragItem(ptOffset);

}

void CThumbListUI::MoveItem(int nFromItem, int nBeforItem)
{
	CThumbListItemUI	*pControlMove=NULL, *pControl=NULL;
	int					it=0, nIndexItem=-1;

	pControlMove = static_cast<CThumbListItemUI*>(m_items[nFromItem]);

	if (nFromItem == -1 || nFromItem == nBeforItem)
		return;
	if (nBeforItem>nFromItem)
		nBeforItem--;

	m_items.Remove(nFromItem);
	for( it = nFromItem; it < m_items.GetSize(); it++ ) 
	{
        pControl = static_cast<CThumbListItemUI*>(m_items[it]);
		if (pControl)
		{
			nIndexItem = pControl->GetIndex();
			{
				nIndexItem--;
				pControl->SetIndex(nIndexItem);
			}
		}
	}

	pControlMove->SetIndex(nBeforItem);
	m_items.InsertAt(nBeforItem,pControlMove);
	for( it = nBeforItem+1; it < m_items.GetSize(); it++ ) 
	{
        pControl = static_cast<CThumbListItemUI*>(m_items[it]);
		if (pControl)
		{
			nIndexItem = pControl->GetIndex();
			{
				nIndexItem++;
				pControl->SetIndex(nIndexItem);
			}
		}
	}
	
}

int CThumbListUI::GetItemCount(void)
{
	return m_items.GetSize();
}

void CThumbListUI::DeleteSelItem(void)
{
	CThumbListItemUI	*pControl=NULL;
	int					nCurIndex = -1, nIndexItem;

	for( int it = 0; it < m_items.GetSize(); it++ ) 
	{
        pControl = static_cast<CThumbListItemUI*>(m_items[it]);
		if (pControl)
		{
			nIndexItem = pControl->GetIndex();

			if (pControl->IsSelected())
			{
				m_items.Remove(it);
				nCurIndex = pControl->GetIndex();
				//delete pControl;
				it--;
				
			}
			if (nCurIndex != -1 && nIndexItem>nCurIndex)
			{
				nIndexItem--;
				pControl->SetIndex(nIndexItem);
			}
			//pControl->SelectIt(pt);
		}
	}

	if (nCurIndex != -1)
		Invalidate();
}


int CThumbListUI::GetSelectItem(void)
{
	CThumbListItemUI	*pControl=NULL;
	int					nCurIndex = -1;

	for( int it = 0; it < m_items.GetSize(); it++ ) 
	{
        pControl = static_cast<CThumbListItemUI*>(m_items[it]);
		if (pControl)
		{
			if (pControl->IsSelected())
			{
				nCurIndex = it;
				break;
			}
		}
	}

	return nCurIndex;
}

void CThumbListUI::SetScrollPosX(int nPos)
{
	CSize size;
	size.cx = 0;
	size.cy = nPos;

	SetScrollPos(size);
}
